#include "functions.h"

void set_parameters( int number_of_arguments, char **arguments ){

  int i;
  int elite_flag = 0, population_flag = 0;

  set_initial_parameters();
   
  for( i = 1; i < number_of_arguments ; i++ ){
    if( strcmp( arguments[ i ], "--population" ) == 0 ){
      population_size = atoi( arguments[ ++i ] );
      population_flag = 1;
    }

    else if( strcmp( arguments[ i ], "--alpha" ) == 0 ){
      alpha = atof( arguments[ ++i ] );
    }

    else if( strcmp( arguments[ i ], "--without_msg" ) == 0 ) {
      msg_type = 0;
    }

    else if( strcmp( arguments[ i ], "--elites" ) == 0 ){
      number_of_elites = atoi( arguments[ ++i ] );
      elite_flag = 1;
    }
    
    else if( strcmp( arguments[ i ], "--function" ) == 0 ){
      function_name = arguments[ ++i ];
      populate_upper_and_lower_limits();
    }

    else if( strcmp( arguments[ i ], "--dimensions" ) == 0 ){
      number_of_dimensions = atoi( arguments[ ++i ] );
    } 
    
    else if( strcmp( arguments[ i ], "--evaluations" ) == 0 ){
      max_evaluations = atoi( arguments[ ++i ] );
    }

    else if( strcmp( arguments[ i ], "--seed" ) == 0 ){
      seed = atoi( arguments[ ++i ] );
      srand( seed );
    }

    else {
      print_arguments_description();		
    }

  } // end for

  // もし、ユーザが --population を使用しており、かつ --elites を使用していなければ、
  // number_of_elites を再設定する。
  if( elite_flag == 0 && population_flag == 1 )
    number_of_elites = population_size / 5;  

// print initial parameters
  printf( "\n" );
  printf( "Function\t\t: %s\n", function_name );
  printf( "Number of dimensions\t: %d\n", number_of_dimensions );
  printf( "Upper bound\t\t: %f\n", upper_limit );
  printf( "Lower bound\t\t: %f\n", lower_limit );
  printf( "Max evaluations\t\t: %d\n", max_evaluations );
  printf( "Seed \t\t\t: %d\n", seed );
  printf( "Population Size\t\t: %d\n", population_size );
  printf( "Learning Rate\t\t: %.3f\n", alpha );
  printf( "K = \t\t\t: %d\n", number_of_elites );
  printf( "\n" );
}

void set_initial_parameters(){

  population_size = 50;
  number_of_elites = population_size / 5;
  alpha = 0.01;

  function_name = "Rastrigin-1.0";
  number_of_dimensions = 20;
  upper_limit = 5.12;
  lower_limit = -5.12;

  seed = 0;
  srand( seed );
  msg_type = 1;

  max_evaluations = 1e+7;
  //  max_evaluations = 200000;
  
  number_of_generations = 0;
  number_of_evaluations = 0;
  termination_eps = 1e-7;
  //  termination_eps = -1000;

}

void populate_upper_and_lower_limits(){
  if( strncmp( function_name, "Rastrigin-1.0", strlen( "Rastrigin-1.0" ) ) == 0 ){
    upper_limit = 5.12;
    lower_limit = -5.12;
	
  } else if( strncmp( function_name, "RotatedRastrigin-1.0", strlen( "RotatedRastrigin-1.0" ) ) == 0 ) {
    upper_limit = 5.12;
    lower_limit = -5.12;
  
  } else if( strncmp( function_name, "Ellipsoid", strlen( "Ellipsoid" ) ) == 0 ) {
    upper_limit = 5.12;
    lower_limit = -5.12;

  } else if( strncmp( function_name, "k-tablet", strlen( "k-tablet" ) ) == 0 ) {
    upper_limit = 5.12;
    lower_limit = -5.12;

  } else if( strncmp( function_name, "Sphere", strlen( "Sphere" ) ) == 0 ) {
    upper_limit = 5.12;
    lower_limit = -5.12;

  } else if( strncmp( function_name, "Rosenbrock-Star", strlen( "Rosenbrock-Star" ) ) == 0 ) {
    upper_limit = 2.048;
    lower_limit = -2.048;

  } else if( strncmp( function_name, "Rosenbrock-Chain", strlen( "Rosenbrock-Chain" ) ) == 0 ) {
    upper_limit = 2.048;
    lower_limit = -2.048;
	
  } else if( strncmp( function_name, "Schwefel", strlen( "Schwefel" ) ) == 0 ){
    upper_limit = 512.0;
    lower_limit = -512.0;
		
  } else if( strncmp( function_name, "Ridge", strlen( "Ridge" ) ) == 0 ){
    upper_limit = 64.0;
    lower_limit = -64.0;
		
  } else if( strncmp( function_name, "Griewank", strlen( "Griewank" ) ) == 0 ){
    upper_limit = 512.0;
    lower_limit = -512.0;
		
  } else if( strncmp( function_name, "Bohachevsky", strlen( "Bohachevsky" ) ) == 0 ){
    upper_limit = 5.12;
    lower_limit = -5.12;

  } else if( strncmp( function_name, "Ackley", strlen( "Ackley" ) ) == 0 ){
    upper_limit = 32.768;
    lower_limit = -32.768;

  } else if( strncmp( function_name, "Schaffer", strlen( "Schaffer" ) ) == 0 ){
    upper_limit = 100;
    lower_limit = -100;

  } else if( strncmp( function_name, "f1", strlen( "f1" ) ) == 0 ){
    upper_limit = 3;
    lower_limit = -3;

  } else if( strncmp( function_name, "f2", strlen( "f2" ) ) == 0 ){
    upper_limit = 3;
    lower_limit = -3;

  } else if( strncmp( function_name, "f3", strlen( "f3" ) ) == 0 ){
    upper_limit = 3;
    lower_limit = -3;

  } else if( strncmp( function_name, "f7", strlen( "f7" ) ) == 0 ){
      upper_limit = 30;
      lower_limit = -30;

  } else if( strncmp( function_name, "f8", strlen( "f8" ) ) == 0 ){
    upper_limit = 100;
    lower_limit = -100;

  } else {
    printf( "%s: invalid problem name\n", function_name );
    exit( 2 );
    
  }
}

void print_arguments_description(){
  printf( "argument \t\t: description ( default value )\n" );
  printf( "--population \t\t: Population Size ( %d )\n", population_size );
  printf( "--alpha \t\t: Learning Rate ( %f )\n", alpha );
  printf( "--elites \t\t: Number of Elites ( %d )\n", number_of_elites );
  printf( "--function \t\t: function name ( %s )\n", function_name );
  printf( "          \t\t  [ Rastrigin-1.0, RotatedRastrigin, Rosenbrock-Star, Rosenbrock-Chain, Schwefel\n");
  printf( "          \t\t    Ridge, Griewank, Sphere, Ellipsoid, k-tablet, Bohachevsky, Ackley, Schaffer ]\n");
  printf( "          \t\t    f1, f2, f3, f7, f8 ]\n");
  printf( "--dimensions \t\t: number of dimensions ( %d )\n", number_of_dimensions );
  printf( "--evaluations \t\t: number of evaluations ( %d )\n", max_evaluations );
  printf( "--seed \t\t\t: integer value ( %d )\n", seed );
  
  exit( 2 );
}

